home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / python2.5 / trace.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-05-11  |  21.0 KB  |  720 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''program/module to trace Python program or function execution
  5.  
  6. Sample use, command line:
  7.   trace.py -c -f counts --ignore-dir \'$prefix\' spam.py eggs
  8.   trace.py -t --ignore-dir \'$prefix\' spam.py eggs
  9.   trace.py --trackcalls spam.py eggs
  10.  
  11. Sample use, programmatically
  12.   import sys
  13.  
  14.   # create a Trace object, telling it what to ignore, and whether to
  15.   # do tracing or line-counting or both.
  16.   tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
  17.                     count=1)
  18.   # run the new command using the given tracer
  19.   tracer.run(\'main()\')
  20.   # make a report, placing output in /tmp
  21.   r = tracer.results()
  22.   r.write_results(show_missing=True, coverdir="/tmp")
  23. '''
  24. import linecache
  25. import os
  26. import re
  27. import sys
  28. import threading
  29. import token
  30. import tokenize
  31. import types
  32. import gc
  33.  
  34. try:
  35.     import cPickle
  36.     pickle = cPickle
  37. except ImportError:
  38.     import pickle
  39.  
  40.  
  41. def usage(outfile):
  42.     outfile.write("Usage: %s [OPTIONS] <file> [ARGS]\n\nMeta-options:\n--help                Display this help then exit.\n--version             Output version information then exit.\n\nOtherwise, exactly one of the following three options must be given:\n-t, --trace           Print each line to sys.stdout before it is executed.\n-c, --count           Count the number of times each line is executed\n                      and write the counts to <module>.cover for each\n                      module executed, in the module's directory.\n                      See also `--coverdir', `--file', `--no-report' below.\n-l, --listfuncs       Keep track of which functions are executed at least\n                      once and write the results to sys.stdout after the\n                      program exits.\n-T, --trackcalls      Keep track of caller/called pairs and write the\n                      results to sys.stdout after the program exits.\n-r, --report          Generate a report from a counts file; do not execute\n                      any code.  `--file' must specify the results file to\n                      read, which must have been created in a previous run\n                      with `--count --file=FILE'.\n\nModifiers:\n-f, --file=<file>     File to accumulate counts over several runs.\n-R, --no-report       Do not generate the coverage report files.\n                      Useful if you want to accumulate over several runs.\n-C, --coverdir=<dir>  Directory where the report files.  The coverage\n                      report for <package>.<module> is written to file\n                      <dir>/<package>/<module>.cover.\n-m, --missing         Annotate executable lines that were not executed\n                      with '>>>>>> '.\n-s, --summary         Write a brief summary on stdout for each file.\n                      (Can only be used with --count or --report.)\n\nFilters, may be repeated multiple times:\n--ignore-module=<mod> Ignore the given module and its submodules\n                      (if it is a package).\n--ignore-dir=<dir>    Ignore files in the given directory (multiple\n                      directories can be joined by os.pathsep).\n" % sys.argv[0])
  43.  
  44. PRAGMA_NOCOVER = '#pragma NO COVER'
  45. rx_blank = re.compile('^\\s*(#.*)?$')
  46.  
  47. class Ignore:
  48.     
  49.     def __init__(self, modules = None, dirs = None):
  50.         if not modules:
  51.             pass
  52.         self._mods = []
  53.         if not dirs:
  54.             pass
  55.         self._dirs = []
  56.         self._dirs = map(os.path.normpath, self._dirs)
  57.         self._ignore = {
  58.             '<string>': 1 }
  59.  
  60.     
  61.     def names(self, filename, modulename):
  62.         if self._ignore.has_key(modulename):
  63.             return self._ignore[modulename]
  64.         
  65.         for mod in self._mods:
  66.             if mod == modulename:
  67.                 self._ignore[modulename] = 1
  68.                 return 1
  69.             
  70.             n = len(mod)
  71.             if mod == modulename[:n] and modulename[n] == '.':
  72.                 self._ignore[modulename] = 1
  73.                 return 1
  74.                 continue
  75.         
  76.         if filename is None:
  77.             self._ignore[modulename] = 1
  78.             return 1
  79.         
  80.         for d in self._dirs:
  81.             if filename.startswith(d + os.sep):
  82.                 self._ignore[modulename] = 1
  83.                 return 1
  84.                 continue
  85.         
  86.         self._ignore[modulename] = 0
  87.         return 0
  88.  
  89.  
  90.  
  91. def modname(path):
  92.     '''Return a plausible module name for the patch.'''
  93.     base = os.path.basename(path)
  94.     (filename, ext) = os.path.splitext(base)
  95.     return filename
  96.  
  97.  
  98. def fullmodname(path):
  99.     '''Return a plausible module name for the path.'''
  100.     comparepath = os.path.normcase(path)
  101.     longest = ''
  102.     for dir in sys.path:
  103.         dir = os.path.normcase(dir)
  104.         if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep:
  105.             if len(dir) > len(longest):
  106.                 longest = dir
  107.             
  108.         len(dir) > len(longest)
  109.     
  110.     if longest:
  111.         base = path[len(longest) + 1:]
  112.     else:
  113.         base = path
  114.     base = base.replace(os.sep, '.')
  115.     if os.altsep:
  116.         base = base.replace(os.altsep, '.')
  117.     
  118.     (filename, ext) = os.path.splitext(base)
  119.     return filename
  120.  
  121.  
  122. class CoverageResults:
  123.     
  124.     def __init__(self, counts = None, calledfuncs = None, infile = None, callers = None, outfile = None):
  125.         self.counts = counts
  126.         if self.counts is None:
  127.             self.counts = { }
  128.         
  129.         self.counter = self.counts.copy()
  130.         self.calledfuncs = calledfuncs
  131.         if self.calledfuncs is None:
  132.             self.calledfuncs = { }
  133.         
  134.         self.calledfuncs = self.calledfuncs.copy()
  135.         self.callers = callers
  136.         if self.callers is None:
  137.             self.callers = { }
  138.         
  139.         self.callers = self.callers.copy()
  140.         self.infile = infile
  141.         self.outfile = outfile
  142.         if self.infile:
  143.             
  144.             try:
  145.                 (counts, calledfuncs, callers) = pickle.load(open(self.infile, 'rb'))
  146.                 self.update(self.__class__(counts, calledfuncs, callers))
  147.             except (IOError, EOFError, ValueError):
  148.                 err = None
  149.                 print >>sys.stderr, 'Skipping counts file %r: %s' % (self.infile, err)
  150.             except:
  151.                 None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  152.             
  153.  
  154.         None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  155.  
  156.     
  157.     def update(self, other):
  158.         '''Merge in the data from another CoverageResults'''
  159.         counts = self.counts
  160.         calledfuncs = self.calledfuncs
  161.         callers = self.callers
  162.         other_counts = other.counts
  163.         other_calledfuncs = other.calledfuncs
  164.         other_callers = other.callers
  165.         for key in other_counts.keys():
  166.             counts[key] = counts.get(key, 0) + other_counts[key]
  167.         
  168.         for key in other_calledfuncs.keys():
  169.             calledfuncs[key] = 1
  170.         
  171.         for key in other_callers.keys():
  172.             callers[key] = 1
  173.         
  174.  
  175.     
  176.     def write_results(self, show_missing = True, summary = False, coverdir = None):
  177.         '''
  178.         @param coverdir
  179.         '''
  180.         if self.calledfuncs:
  181.             print 
  182.             print 'functions called:'
  183.             calls = self.calledfuncs.keys()
  184.             calls.sort()
  185.             for filename, modulename, funcname in calls:
  186.                 print 'filename: %s, modulename: %s, funcname: %s' % (filename, modulename, funcname)
  187.             
  188.         
  189.         if self.callers:
  190.             print 
  191.             print 'calling relationships:'
  192.             calls = self.callers.keys()
  193.             calls.sort()
  194.             lastfile = lastcfile = ''
  195.             for pfile, pmod, pfunc in calls:
  196.                 (cfile, cmod, cfunc) = None
  197.                 if pfile != lastfile:
  198.                     print 
  199.                     print '***', pfile, '***'
  200.                     lastfile = pfile
  201.                     lastcfile = ''
  202.                 
  203.                 if cfile != pfile and lastcfile != cfile:
  204.                     print '  -->', cfile
  205.                     lastcfile = cfile
  206.                 
  207.                 print '    %s.%s -> %s.%s' % (pmod, pfunc, cmod, cfunc)
  208.             
  209.         
  210.         per_file = { }
  211.         for filename, lineno in self.counts.keys():
  212.             lines_hit = per_file[filename] = per_file.get(filename, { })
  213.             lines_hit[lineno] = self.counts[(filename, lineno)]
  214.         
  215.         sums = { }
  216.         for filename, count in per_file.iteritems():
  217.             if filename == '<string>':
  218.                 continue
  219.             
  220.             if filename.endswith(('.pyc', '.pyo')):
  221.                 filename = filename[:-1]
  222.             
  223.             if coverdir is None:
  224.                 dir = os.path.dirname(os.path.abspath(filename))
  225.                 modulename = modname(filename)
  226.             else:
  227.                 dir = coverdir
  228.                 if not os.path.exists(dir):
  229.                     os.makedirs(dir)
  230.                 
  231.                 modulename = fullmodname(filename)
  232.             if show_missing:
  233.                 lnotab = find_executable_linenos(filename)
  234.             else:
  235.                 lnotab = { }
  236.             source = linecache.getlines(filename)
  237.             coverpath = os.path.join(dir, modulename + '.cover')
  238.             (n_hits, n_lines) = self.write_results_file(coverpath, source, lnotab, count)
  239.             if summary and n_lines:
  240.                 percent = int(100 * n_hits / n_lines)
  241.                 sums[modulename] = (n_lines, percent, modulename, filename)
  242.                 continue
  243.         
  244.         if summary and sums:
  245.             mods = sums.keys()
  246.             mods.sort()
  247.             print 'lines   cov%   module   (path)'
  248.             for m in mods:
  249.                 (n_lines, percent, modulename, filename) = sums[m]
  250.                 print '%5d   %3d%%   %s   (%s)' % sums[m]
  251.             
  252.         
  253.         if self.outfile:
  254.             
  255.             try:
  256.                 pickle.dump((self.counts, self.calledfuncs, self.callers), open(self.outfile, 'wb'), 1)
  257.             except IOError:
  258.                 err = None
  259.                 print >>sys.stderr, "Can't save counts files because %s" % err
  260.             except:
  261.                 None<EXCEPTION MATCH>IOError
  262.             
  263.  
  264.         None<EXCEPTION MATCH>IOError
  265.  
  266.     
  267.     def write_results_file(self, path, lines, lnotab, lines_hit):
  268.         '''Return a coverage results file in path.'''
  269.         
  270.         try:
  271.             outfile = open(path, 'w')
  272.         except IOError:
  273.             err = None
  274.             print >>sys.stderr, 'trace: Could not open %r for writing: %s- skipping' % (path, err)
  275.             return (0, 0)
  276.  
  277.         n_lines = 0
  278.         n_hits = 0
  279.         for i, line in enumerate(lines):
  280.             lineno = i + 1
  281.             if lineno in lines_hit:
  282.                 outfile.write('%5d: ' % lines_hit[lineno])
  283.                 n_hits += 1
  284.                 n_lines += 1
  285.             elif rx_blank.match(line):
  286.                 outfile.write('       ')
  287.             elif lineno in lnotab and PRAGMA_NOCOVER not in lines[i]:
  288.                 outfile.write('>>>>>> ')
  289.                 n_lines += 1
  290.             else:
  291.                 outfile.write('       ')
  292.             outfile.write(lines[i].expandtabs(8))
  293.         
  294.         outfile.close()
  295.         return (n_hits, n_lines)
  296.  
  297.  
  298.  
  299. def find_lines_from_code(code, strs):
  300.     '''Return dict where keys are lines in the line number table.'''
  301.     linenos = { }
  302.     line_increments = [ ord(c) for c in code.co_lnotab[1::2] ]
  303.     table_length = len(line_increments)
  304.     docstring = False
  305.     lineno = code.co_firstlineno
  306.     for li in line_increments:
  307.         lineno += li
  308.         if lineno not in strs:
  309.             linenos[lineno] = 1
  310.             continue
  311.         []
  312.     
  313.     return linenos
  314.  
  315.  
  316. def find_lines(code, strs):
  317.     '''Return lineno dict for all code objects reachable from code.'''
  318.     linenos = find_lines_from_code(code, strs)
  319.     for c in code.co_consts:
  320.         if isinstance(c, types.CodeType):
  321.             linenos.update(find_lines(c, strs))
  322.             continue
  323.     
  324.     return linenos
  325.  
  326.  
  327. def find_strings(filename):
  328.     '''Return a dict of possible docstring positions.
  329.  
  330.     The dict maps line numbers to strings.  There is an entry for
  331.     line that contains only a string or a part of a triple-quoted
  332.     string.
  333.     '''
  334.     d = { }
  335.     prev_ttype = token.INDENT
  336.     f = open(filename)
  337.     for ttype, tstr, start, end, line in tokenize.generate_tokens(f.readline):
  338.         if ttype == token.STRING:
  339.             if prev_ttype == token.INDENT:
  340.                 (sline, scol) = start
  341.                 (eline, ecol) = end
  342.                 for i in range(sline, eline + 1):
  343.                     d[i] = 1
  344.                 
  345.             
  346.         
  347.         prev_ttype = ttype
  348.     
  349.     f.close()
  350.     return d
  351.  
  352.  
  353. def find_executable_linenos(filename):
  354.     '''Return dict where keys are line numbers in the line number table.'''
  355.     
  356.     try:
  357.         prog = open(filename, 'rU').read()
  358.     except IOError:
  359.         err = None
  360.         print >>sys.stderr, 'Not printing coverage data for %r: %s' % (filename, err)
  361.         return { }
  362.  
  363.     code = compile(prog, filename, 'exec')
  364.     strs = find_strings(filename)
  365.     return find_lines(code, strs)
  366.  
  367.  
  368. class Trace:
  369.     
  370.     def __init__(self, count = 1, trace = 1, countfuncs = 0, countcallers = 0, ignoremods = (), ignoredirs = (), infile = None, outfile = None):
  371.         """
  372.         @param count true iff it should count number of times each
  373.                      line is executed
  374.         @param trace true iff it should print out each line that is
  375.                      being counted
  376.         @param countfuncs true iff it should just output a list of
  377.                      (filename, modulename, funcname,) for functions
  378.                      that were called at least once;  This overrides
  379.                      `count' and `trace'
  380.         @param ignoremods a list of the names of modules to ignore
  381.         @param ignoredirs a list of the names of directories to ignore
  382.                      all of the (recursive) contents of
  383.         @param infile file from which to read stored counts to be
  384.                      added into the results
  385.         @param outfile file in which to write the results
  386.         """
  387.         self.infile = infile
  388.         self.outfile = outfile
  389.         self.ignore = Ignore(ignoremods, ignoredirs)
  390.         self.counts = { }
  391.         self.blabbed = { }
  392.         self.pathtobasename = { }
  393.         self.donothing = 0
  394.         self.trace = trace
  395.         self._calledfuncs = { }
  396.         self._callers = { }
  397.         self._caller_cache = { }
  398.         if countcallers:
  399.             self.globaltrace = self.globaltrace_trackcallers
  400.         elif countfuncs:
  401.             self.globaltrace = self.globaltrace_countfuncs
  402.         elif trace and count:
  403.             self.globaltrace = self.globaltrace_lt
  404.             self.localtrace = self.localtrace_trace_and_count
  405.         elif trace:
  406.             self.globaltrace = self.globaltrace_lt
  407.             self.localtrace = self.localtrace_trace
  408.         elif count:
  409.             self.globaltrace = self.globaltrace_lt
  410.             self.localtrace = self.localtrace_count
  411.         else:
  412.             self.donothing = 1
  413.  
  414.     
  415.     def run(self, cmd):
  416.         import __main__
  417.         dict = __main__.__dict__
  418.         if not self.donothing:
  419.             sys.settrace(self.globaltrace)
  420.             threading.settrace(self.globaltrace)
  421.         
  422.         
  423.         try:
  424.             exec cmd in dict, dict
  425.         finally:
  426.             if not self.donothing:
  427.                 sys.settrace(None)
  428.                 threading.settrace(None)
  429.             
  430.  
  431.  
  432.     
  433.     def runctx(self, cmd, globals = None, locals = None):
  434.         if globals is None:
  435.             globals = { }
  436.         
  437.         if locals is None:
  438.             locals = { }
  439.         
  440.         if not self.donothing:
  441.             sys.settrace(self.globaltrace)
  442.             threading.settrace(self.globaltrace)
  443.         
  444.         
  445.         try:
  446.             exec cmd in globals, locals
  447.         finally:
  448.             if not self.donothing:
  449.                 sys.settrace(None)
  450.                 threading.settrace(None)
  451.             
  452.  
  453.  
  454.     
  455.     def runfunc(self, func, *args, **kw):
  456.         result = None
  457.         if not self.donothing:
  458.             sys.settrace(self.globaltrace)
  459.         
  460.         
  461.         try:
  462.             result = func(*args, **kw)
  463.         finally:
  464.             if not self.donothing:
  465.                 sys.settrace(None)
  466.             
  467.  
  468.         return result
  469.  
  470.     
  471.     def file_module_function_of(self, frame):
  472.         code = frame.f_code
  473.         filename = code.co_filename
  474.         if filename:
  475.             modulename = modname(filename)
  476.         else:
  477.             modulename = None
  478.         funcname = code.co_name
  479.         clsname = None
  480.         return (filename, modulename, funcname)
  481.  
  482.     
  483.     def globaltrace_trackcallers(self, frame, why, arg):
  484.         '''Handler for call events.
  485.  
  486.         Adds information about who called who to the self._callers dict.
  487.         '''
  488.         if why == 'call':
  489.             this_func = self.file_module_function_of(frame)
  490.             parent_func = self.file_module_function_of(frame.f_back)
  491.             self._callers[(parent_func, this_func)] = 1
  492.         
  493.  
  494.     
  495.     def globaltrace_countfuncs(self, frame, why, arg):
  496.         '''Handler for call events.
  497.  
  498.         Adds (filename, modulename, funcname) to the self._calledfuncs dict.
  499.         '''
  500.         if why == 'call':
  501.             this_func = self.file_module_function_of(frame)
  502.             self._calledfuncs[this_func] = 1
  503.         
  504.  
  505.     
  506.     def globaltrace_lt(self, frame, why, arg):
  507.         """Handler for call events.
  508.  
  509.         If the code block being entered is to be ignored, returns `None',
  510.         else returns self.localtrace.
  511.         """
  512.         if why == 'call':
  513.             code = frame.f_code
  514.             filename = frame.f_globals.get('__file__', None)
  515.             if filename:
  516.                 modulename = modname(filename)
  517.                 if modulename is not None:
  518.                     ignore_it = self.ignore.names(filename, modulename)
  519.                     if not ignore_it:
  520.                         if self.trace:
  521.                             print ' --- modulename: %s, funcname: %s' % (modulename, code.co_name)
  522.                         
  523.                         return self.localtrace
  524.                     
  525.                 
  526.             else:
  527.                 return None
  528.         
  529.  
  530.     
  531.     def localtrace_trace_and_count(self, frame, why, arg):
  532.         if why == 'line':
  533.             filename = frame.f_code.co_filename
  534.             lineno = frame.f_lineno
  535.             key = (filename, lineno)
  536.             self.counts[key] = self.counts.get(key, 0) + 1
  537.             bname = os.path.basename(filename)
  538.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  539.         
  540.         return self.localtrace
  541.  
  542.     
  543.     def localtrace_trace(self, frame, why, arg):
  544.         if why == 'line':
  545.             filename = frame.f_code.co_filename
  546.             lineno = frame.f_lineno
  547.             bname = os.path.basename(filename)
  548.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  549.         
  550.         return self.localtrace
  551.  
  552.     
  553.     def localtrace_count(self, frame, why, arg):
  554.         if why == 'line':
  555.             filename = frame.f_code.co_filename
  556.             lineno = frame.f_lineno
  557.             key = (filename, lineno)
  558.             self.counts[key] = self.counts.get(key, 0) + 1
  559.         
  560.         return self.localtrace
  561.  
  562.     
  563.     def results(self):
  564.         return CoverageResults(self.counts, infile = self.infile, outfile = self.outfile, calledfuncs = self._calledfuncs, callers = self._callers)
  565.  
  566.  
  567.  
  568. def _err_exit(msg):
  569.     sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  570.     sys.exit(1)
  571.  
  572.  
  573. def main(argv = None):
  574.     import getopt
  575.     if argv is None:
  576.         argv = sys.argv
  577.     
  578.     
  579.     try:
  580.         (opts, prog_argv) = getopt.getopt(argv[1:], 'tcrRf:d:msC:lT', [
  581.             'help',
  582.             'version',
  583.             'trace',
  584.             'count',
  585.             'report',
  586.             'no-report',
  587.             'summary',
  588.             'file=',
  589.             'missing',
  590.             'ignore-module=',
  591.             'ignore-dir=',
  592.             'coverdir=',
  593.             'listfuncs',
  594.             'trackcalls'])
  595.     except getopt.error:
  596.         msg = None
  597.         sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  598.         sys.stderr.write("Try `%s --help' for more information\n" % sys.argv[0])
  599.         sys.exit(1)
  600.  
  601.     trace = 0
  602.     count = 0
  603.     report = 0
  604.     no_report = 0
  605.     counts_file = None
  606.     missing = 0
  607.     ignore_modules = []
  608.     ignore_dirs = []
  609.     coverdir = None
  610.     summary = 0
  611.     listfuncs = False
  612.     countcallers = False
  613.     for opt, val in opts:
  614.         if opt == '--help':
  615.             usage(sys.stdout)
  616.             sys.exit(0)
  617.         
  618.         if opt == '--version':
  619.             sys.stdout.write('trace 2.0\n')
  620.             sys.exit(0)
  621.         
  622.         if opt == '-T' or opt == '--trackcalls':
  623.             countcallers = True
  624.             continue
  625.         
  626.         if opt == '-l' or opt == '--listfuncs':
  627.             listfuncs = True
  628.             continue
  629.         
  630.         if opt == '-t' or opt == '--trace':
  631.             trace = 1
  632.             continue
  633.         
  634.         if opt == '-c' or opt == '--count':
  635.             count = 1
  636.             continue
  637.         
  638.         if opt == '-r' or opt == '--report':
  639.             report = 1
  640.             continue
  641.         
  642.         if opt == '-R' or opt == '--no-report':
  643.             no_report = 1
  644.             continue
  645.         
  646.         if opt == '-f' or opt == '--file':
  647.             counts_file = val
  648.             continue
  649.         
  650.         if opt == '-m' or opt == '--missing':
  651.             missing = 1
  652.             continue
  653.         
  654.         if opt == '-C' or opt == '--coverdir':
  655.             coverdir = val
  656.             continue
  657.         
  658.         if opt == '-s' or opt == '--summary':
  659.             summary = 1
  660.             continue
  661.         
  662.         if opt == '--ignore-module':
  663.             ignore_modules.append(val)
  664.             continue
  665.         
  666.         if opt == '--ignore-dir':
  667.             for s in val.split(os.pathsep):
  668.                 s = os.path.expandvars(s)
  669.                 s = s.replace('$prefix', os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3]))
  670.                 s = s.replace('$exec_prefix', os.path.join(sys.exec_prefix, 'lib', 'python' + sys.version[:3]))
  671.                 s = os.path.normpath(s)
  672.                 ignore_dirs.append(s)
  673.             
  674.             continue
  675.         
  676.         if not 0:
  677.             raise AssertionError, 'Should never get here'
  678.     
  679.     if listfuncs:
  680.         if count or trace:
  681.             _err_exit('cannot specify both --listfuncs and (--trace or --count)')
  682.         
  683.     if not count and trace and report and listfuncs or countcallers:
  684.         _err_exit('must specify one of --trace, --count, --report, --listfuncs, or --trackcalls')
  685.     
  686.     if report and no_report:
  687.         _err_exit('cannot specify both --report and --no-report')
  688.     
  689.     if report and not counts_file:
  690.         _err_exit('--report requires a --file')
  691.     
  692.     if no_report and len(prog_argv) == 0:
  693.         _err_exit('missing name of file to run')
  694.     
  695.     if report:
  696.         results = CoverageResults(infile = counts_file, outfile = counts_file)
  697.         results.write_results(missing, summary = summary, coverdir = coverdir)
  698.     else:
  699.         sys.argv = prog_argv
  700.         progname = prog_argv[0]
  701.         sys.path[0] = os.path.split(progname)[0]
  702.         t = Trace(count, trace, countfuncs = listfuncs, countcallers = countcallers, ignoremods = ignore_modules, ignoredirs = ignore_dirs, infile = counts_file, outfile = counts_file)
  703.         
  704.         try:
  705.             t.run('execfile(%r)' % (progname,))
  706.         except IOError:
  707.             err = None
  708.             _err_exit('Cannot run file %r because: %s' % (sys.argv[0], err))
  709.         except SystemExit:
  710.             pass
  711.  
  712.         results = t.results()
  713.         if not no_report:
  714.             results.write_results(missing, summary = summary, coverdir = coverdir)
  715.         
  716.  
  717. if __name__ == '__main__':
  718.     main()
  719.  
  720.